package net.qiqbframework.commandhandling;

import net.qiqbframework.messaging.GenericMessage;
import net.qiqbframework.messaging.Message;
import net.qiqbframework.messaging.MessageDecorator;
import net.qiqbframework.messaging.MetaData;

import javax.annotation.Nonnull;
import java.util.Map;


public class GenericCommandMessage<T> extends MessageDecorator<T> implements CommandMessage<T> {

    private final String commandName;

    /**
     * 将一个对象组装一个命令消息
     *
     * @param command
     * @param <C>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <C> CommandMessage<C> of(@Nonnull Object command) {
        if (command instanceof CommandMessage) {
            return (CommandMessage<C>) command;
        } else if (command instanceof Message) {
            return new GenericCommandMessage<>(
                    (C) ((Message<?>) command).getPayload(), ((Message<?>) command).getMetaData()
            );
        }
        return new GenericCommandMessage<>((C) command, MetaData.emptyInstance());
    }


    public GenericCommandMessage(@Nonnull T payload) {
        this(payload, MetaData.emptyInstance());
    }

    public GenericCommandMessage(@Nonnull T payload, @Nonnull Map<String, ?> metaData) {
        this(new GenericMessage<>(payload, metaData), payload.getClass().getName());
    }

    public GenericCommandMessage(@Nonnull Message<T> delegate, @Nonnull String commandName) {
        super(delegate);
        this.commandName = commandName;
    }

    @Override
    public String getCommandName() {
        return commandName;
    }


    @Override
    protected void describeTo(StringBuilder stringBuilder) {
        super.describeTo(stringBuilder);
        stringBuilder.append(", commandName='")
                .append(getCommandName())
                .append('\'');
    }

    @Override
    protected String describeType() {
        return "GenericCommandMessage";
    }


}
